home *** CD-ROM | disk | FTP | other *** search
- /*
- * moire idle desk accessory
- *
- * bounce points with random speeds
- * generate queue of rectangles
- * inscribe shapes within rectangles
- * draw in XOR mode so stuff at end of queue can be erased
- *
- * keyboard commands:
- *
- * [ shorten queue
- * ] lengthen queue
- * q quantize point speed
- * 0-9 set limit for point speed (0 means none)
- *
- * other keys select shapes (default is rectangle)
- * o oval
- * t tri-angle
- * p penta-gram
- * ...
- */
- #include <hd20:lightspeed:mac:quickdraw.h>
-
- #define nQueue 100 /* max size of queue */
- #define qInit 30 /* initial size of queue */
- #define qIncr 10 /* size increment */
-
- int shape; /* current shape */
- int quantize; /* quantize delta's */
- long limit; /* limit for delta's */
- /*
- * bouncing points - 1st is value, 2nd is delta, each w/16 bit fraction
- */
- long x1[2], y1[2],
- x2[2], y2[2];
- /*
- * rectangle queue
- */
- int qHead, qTail, qSize, nRinQ;
- Rect rQueue[nQueue];
- /*
- * compute new delta
- */
- long
- newDelta(range)
- {
- register int r;
- register long d;
-
- if ((r = Random()) < 0)
- r = -r;
- d = ((long)range << 16) / (r % range + 1);
- if (quantize && (d = (d + 0x7FFFL) & ~0xFFFFL) == 0)
- d = 0x10000L;
- if (limit && d > limit)
- d = limit;
- return d;
- }
- /*
- * compute new point value - change delta at rails
- */
- newPoint(p, lo, hi)
- long *p;
- int lo, hi;
- {
- register int v;
-
- v = p[0] >> 16;
- if (v < lo) {
- v = lo;
- p[1] = newDelta(hi - lo);
- }
- else if (v > hi) {
- v = hi;
- p[1] = -newDelta(hi - lo);
- }
- p[0] += p[1];
- return v;
- }
- /*
- * draw the current shape
- */
- frameShape(s, rp)
- int s;
- Rect *rp;
- {
- register int m, n;
-
- m = rp->left + (rp->right - rp->left) / 2;
- n = rp->top + (rp->bottom - rp->top) / 2;
- switch (s) {
- default:
- FrameRect(rp);
- break;
- case 'o':
- FrameOval(rp);
- break;
- case 't': /* tri-angle */
- MoveTo(m, rp->top);
- LineTo(rp->left, rp->bottom);
- LineTo(rp->right, rp->bottom);
- LineTo(m, rp->top);
- break;
- case 'p': /* pentagram */
- MoveTo(m, rp->top);
- LineTo(rp->right, rp->bottom);
- LineTo(rp->left, n);
- LineTo(rp->right, n);
- LineTo(rp->left, rp->bottom);
- LineTo(m, rp->top);
- break;
- case 'd': /* diamond */
- MoveTo(m, rp->top);
- LineTo(rp->right, n);
- LineTo(m, rp->bottom);
- LineTo(rp->left, n);
- LineTo(m, rp->top);
- break;
- case 'h': /* hour glass */
- MoveTo(rp->left, rp->top);
- LineTo(rp->right, rp->top);
- LineTo(rp->left, rp->bottom);
- LineTo(rp->right, rp->bottom);
- LineTo(rp->left, rp->top);
- break;
- case 'x':
- MoveTo(rp->left, rp->top);
- LineTo(rp->right, rp->bottom);
- MoveTo(rp->right, rp->top);
- LineTo(rp->left, rp->bottom);
- break;
- case 'v':
- MoveTo(rp->left, rp->top);
- LineTo(m, rp->bottom);
- LineTo(rp->right, rp->top);
- break;
- case '\\':
- MoveTo(rp->left, rp->top);
- LineTo(rp->right, rp->bottom);
- break;
- case '/':
- MoveTo(rp->right, rp->top);
- LineTo(rp->left, rp->bottom);
- break;
- case '+':
- MoveTo(m, rp->top);
- LineTo(m, rp->bottom);
- MoveTo(rp->right, n);
- LineTo(rp->left, n);
- break;
- }
- }
- /*
- * change shape - redraw stuff in queue
- */
- newShape(s)
- {
- register int x, n;
-
- if (s == shape)
- return;
- ObscureCursor();
- x = qHead;
- n = nRinQ;
- while (n-- > 0) {
- frameShape(shape, &rQueue[x]);
- frameShape(s, &rQueue[x]);
- if (++x >= nQueue)
- x = 0;
- }
- shape = s;
- }
- /*
- * initialize stuff
- */
- initIdle(rp)
- Rect *rp;
- {
- shape = 'o';
- limit = 0;
- quantize = 0;
- nRinQ = 0;
- qHead = 0;
- qTail = 0;
- qSize = qInit;
-
- x1[1] = newDelta(rp->right - rp->left);
- x1[0] = ((long)rp->right << 16) + x1[1];
- y1[1] = newDelta(rp->bottom - rp->top);
- y1[0] = ((long)rp->top << 16) + y1[1];
-
- x2[1] = -newDelta(rp->right - rp->left);
- x2[0] = ((long)rp->left << 16) + x2[1];
- y2[1] = -newDelta(rp->bottom - rp->top);
- y2[0] = ((long)rp->bottom << 16) + y2[1];
- }
- /*
- * one step of the way...
- */
- runIdle(rp)
- Rect *rp;
- {
- Point p1, p2;
-
- ObscureCursor();
- /*
- * undraw stuff at the head - shorten if necessary
- */
- while (nRinQ >= qSize) {
- frameShape(shape, &rQueue[qHead]);
- if (++qHead >= nQueue)
- qHead = 0;
- --nRinQ;
- }
- /*
- * compute new rectangle
- */
- p1.h = newPoint(x1, rp->left, rp->right);
- p1.v = newPoint(y1, rp->top, rp->bottom);
- p2.h = newPoint(x2, rp->left, rp->right);
- p2.v = newPoint(y2, rp->top, rp->bottom);
- /*
- * add rectangle to queue
- */
- Pt2Rect(p1, p2, &rQueue[qTail]);
- frameShape(shape, &rQueue[qTail]);
- if (++qTail >= nQueue)
- qTail = 0;
- ++nRinQ;
- }
- /*
- * key events come here
- */
- keyIdle(c)
- {
- switch (c) {
- case '[': /* shorten */
- if ((qSize -= qIncr) < qIncr)
- qSize = qIncr;
- break;
- case ']': /* lengthen */
- if ((qSize += qIncr) > nQueue)
- qSize = nQueue;
- break;
- default:
- newShape(c);
- break;
- case 'q':
- quantize = !quantize;
- break;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- limit = (long)(c - '0') << 17;
- break;
- }
- return 0;
- }
-